/**
 * Jaxson ajax
 *
 * Copyright Remedy Interactive, licensed under Apache version 2 license:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0.html
 *
 * This notice must remain in all java source files.
 */
package org.jaxson.util.reflection;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author Joe Maisel
 *
 */
public class ReflectionUtil {
	
	public static Object getProperty( Object instance, String property ){
		Object result = null;
		
		Class<? extends Object> cls = instance.getClass();
		
		try {
			Method getter = cls.getMethod(accessor( true, property ));
			result = getter.invoke(instance);
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} 
		
		return result;
	}
	
	public static Class<? extends Object> type( Object instance, String property ){
		
		Class<? extends Object> cls = instance.getClass();
		
		try {
			return cls.getMethod(accessor(true, property)).getReturnType();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
		
		return null;
	}
	
	public static void set( Object instance, String property, String value ){
		Class<? extends Object> cls = instance.getClass();
		Class<? extends Object> type = type( instance, property );
		try {
			
			Object val = null;
			
			if( type.equals(Float.class) || type.equals(float.class) ){
				val = Float.parseFloat(value);
			}
			
			else if( type.equals(Integer.class) || type.equals(int.class) ){
				val = Float.parseFloat(value);
			}

			else if( type.equals(Boolean.class) || type.equals(boolean.class) ){
				val = Boolean.parseBoolean(value);
			}
			
			else if( type.equals(String.class) ){
				val = value;
			}
			
			else{
				throw new IllegalArgumentException( "property may only be an String, Integer, Float, or Boolean" );
			}
			
			cls.getMethod(accessor(false, property), type).invoke(instance, val);
			
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
	}
	
	public static String accessor( boolean isGetter, String property ){
		return (isGetter?"get":"set") + property.substring(0,1).toUpperCase() + property.substring(1);
	}
}
